﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace RTS
{
	public class Building : PosicionableObject, ITimeDependant
	{
		protected float offsetOptionsInterfaceX = 4F;
		protected float offsetOptionsInterfaceY = -15;
		protected float separationOptionsInterface = 4;
		protected float offsetBuildingInterfaceX = 45;
		protected float offsetBuildingInterfaceY = -70;
		protected float constructingTime = 4;

		public const String Idle = "idleBuilding";
		public const String Constructing = "constructingBuilding";
		public const String Spawning = "spawningBuilding";

		protected List<Option> options = new List<Option>();
		private List<OptionGraph> optionsGraph = new List<OptionGraph>();
		protected RTSBuildingTextures buildingTextures;
		protected ContentManager Content;

		private MouseState mousePrevState;

		private bool followMouse = false;

		public Building(GameMain game) : base(game)
		{
			orientation = 0;
			setState(Constructing);
		}

		public override void LoadContent(ContentManager Content)
		{
			this.Content = Content;

			textures = buildingTextures;
			buildingTextures.LoadContent(Content);
		}

		public override void update()
		{
			base.update();
			if (state == Building.Constructing && stateTimeElapsed >= constructingTime) setState(Idle);
			MouseState mouseCurrentState = Mouse.GetState();

			if (isFollowingMouse())
			{
				setPosition(new Position2D(mouseCurrentState.X + camera.CornerPos.X, mouseCurrentState.Y + camera.CornerPos.Y));

				if (mouseCurrentState.LeftButton == ButtonState.Pressed && mousePrevState.LeftButton == ButtonState.Released)
				{
					followMouse = false;
					setState(Constructing);
				}
			}

			mousePrevState = mouseCurrentState;
		}

		public bool isFollowingMouse()
		{
			return followMouse;
		}

		public void setFollowMouse(bool followMouse)
		// Follows the mouse and sets position on next click
		{
			this.followMouse = followMouse;
			mousePrevState = Mouse.GetState();
			setState(Idle);
		}

		public override void Draw(SpriteBatch spriteBatch)
		{
			base.Draw(spriteBatch);

			if (isSelected) drawBuildingInterface(spriteBatch);
		}

		protected override void drawInMiddle(SpriteBatch spriteBatch)
		{
			drawObject(spriteBatch, buildingTextures.GetTexture(state), buildingTextures.TextureSize);
		}

		private void drawBuildingInterface(SpriteBatch spriteBatch)
		{
			optionsGraph = new List<OptionGraph>();

			TextureSize textureSize = buildingTextures.TextureSize;
			Texture2D buildingInterfaceTexture = buildingTextures.GetGraphicInterfaceTexture();

			Vector2 drawingVector = getDrawingVector();
			drawingVector.X += offsetBuildingInterfaceX;
			drawingVector.Y += offsetBuildingInterfaceY;

			spriteBatch.Draw(buildingInterfaceTexture, drawingVector, null, Color.White, 0, new Vector2(0, 0), camera.Scale, SpriteEffects.None, 0);

			for (int i = 0; i < options.Count; i++)
			{
				Texture2D optionTextureCurrent = buildingTextures.GetgraphicInterfaceOptionTexture();

				float xPos = drawingVector.X + i * camera.Scale * (optionTextureCurrent.Width + separationOptionsInterface) + offsetOptionsInterfaceX;
				float yPos = drawingVector.Y + offsetOptionsInterfaceY;

				Rectangle rectanglePosition = new Rectangle((int)xPos, (int)yPos, (int)(optionTextureCurrent.Width * camera.Scale), (int)(optionTextureCurrent.Height * camera.Scale));
				optionsGraph.Add(new OptionGraph(options[i], rectanglePosition));

				spriteBatch.Draw(optionTextureCurrent, new Vector2(xPos, yPos), null, Color.White, 0, new Vector2(0, 0), camera.Scale, SpriteEffects.None, 0);
			}
		}

		public override bool isClicked(int mouseX, int mouseY)
		{
			if (base.isClicked(mouseX, mouseY)) return true;

			if (getOptionSelected(mouseX, mouseY) == null) return false;

			return true;
		}


		public Option getOptionSelected(int mouseX, int mouseY)
		{
			foreach (OptionGraph optionGraph in optionsGraph)
			{
				if (optionGraph.isBeingClicked(mouseX, mouseY)) return optionGraph.getOption();
			}

			return null;
		}

		protected override float getDrawingPercentage()
		{
			if (state == Constructing)
			{
				if (stateTimeElapsed >= constructingTime) return (1F - (float)Math.Pow(10, -5));
				return stateTimeElapsed / constructingTime;
			}

			return base.getDrawingPercentage();
		}


		protected void executeOption(Option option)
		{
			option.ExecuteAction(this);
		}

		protected override void setState(String newState)
		{
			base.setState(newState);
			if (state == Constructing) drawByPercentage = true;
		}

		public override void excecuteClickAction(List<PosicionableObject> clickedObjects, MouseState mouse)
		{
			if (mouse.LeftButton == ButtonState.Pressed)
			{
				if (IsSelected())
				{
					Option optionSelected = getOptionSelected(mouse.X, mouse.Y);
					if (optionSelected != null)
					{
						executeOption(optionSelected);
					}
					else
					{
						if (clickedObjects.Contains(this) == false) unselect();
					}
				}
				else
				{
					if (clickedObjects.Contains(this))
					{
						game.selectObject(this);
					}
				}
			}

		}
	}
}
